//this file is part of notepad++
//Copyright (C)2003 Don HO ( donho@altern.org )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include "LogHelperDlg.h"
#include "ContextMenu/ContextMenu.h"
#include "PluginDefinition.h"
#include "WcharMbcsConvertor.h"

#include <vector>
using std::vector;

#include "TCHAR.h"

extern NppData nppData;

LONG LogHelperDlg::originalWndProc = NULL;

LogHelperDlg::LogHelperDlg()
    : DockingDlgInterface(IDD_LOGHELPER)
      ,_pFinder(NULL)
{

};

LogHelperDlg::~LogHelperDlg()
{
    _scintView.destroy();
    delete _pFinder;
}

void LogHelperDlg::init(HINSTANCE hInst, HWND parent)
{
    DockingDlgInterface::init(hInst,_hSelf);	
}

void LogHelperDlg::initScintillaView()
{
	_scintView.init(_hInst,getHSelf());
	_scintView.setReadOnly(true);

	originalWndProc = SetWindowLongPtr(_scintView.getHSelf(), GWLP_WNDPROC, (LONG_PTR)finderProc);

	_scintView.execute(SCI_SETCODEPAGE, SC_CP_UTF8);
	_scintView.execute(SCI_USEPOPUP, FALSE);
	_scintView.execute(SCI_SETUNDOCOLLECTION, false);	//dont store any undo information
	_scintView.execute(SCI_SETCARETLINEVISIBLE, 0);
	_scintView.execute(SCI_SETCARETWIDTH, 0);

    _cp = execute(SCI_GETCODEPAGE, 0, 0);

	_scintView.display();
}

BOOL CALLBACK LogHelperDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message) 
	{
		case WM_COMMAND:
		{
			switch (wParam)
			{
				case CM_SERVER_CALLS:
				{
					findServerCalls();
					return TRUE;;
				}
				default:
				{
					return FALSE;
				}
					
			}
		}
		case WM_CONTEXTMENU:
			{
				if (HWND(wParam) == _scintView.getHSelf())
				{
					POINT p;
					::GetCursorPos(&p);
					ContextMenu scintillaContextmenu;
					vector<MenuItemUnit> tmp;
					tmp.push_back(MenuItemUnit(CM_COLLAPSE_ALL, TEXT("Collapse all")));
					tmp.push_back(MenuItemUnit(CM_UNCOLLAPSE_ALL, TEXT("Uncollapse all")));
					tmp.push_back(MenuItemUnit(0, TEXT("Separator")));
					tmp.push_back(MenuItemUnit(CM_SERVER_CALLS,TEXT("Server calls")));

					scintillaContextmenu.create(_hSelf, tmp);

					scintillaContextmenu.display(p);
					return TRUE;
				}
				return ::DefWindowProc(_hSelf, message, wParam, lParam);
			}

		case WM_SIZE :
			{
				RECT rc;
				getClientRect(rc);
				_scintView.reSizeTo(rc);
			}
			break;

		default :
			return DockingDlgInterface::run_dlgProc(message, wParam, lParam);
	}

	return FALSE;
}

LRESULT FAR PASCAL LogHelperDlg::finderProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message == WM_KEYDOWN && (wParam == VK_DELETE || wParam == VK_RETURN))
	{
		ScintillaView *pScint = (ScintillaView *)(::GetWindowLongPtr(hwnd, GWL_USERDATA));
		LogHelperDlg *pLogHelper = (LogHelperDlg *)(::GetWindowLongPtr(pScint->getHParent(), GWL_USERDATA));
		/*if (wParam == VK_RETURN)
			pLogHelper->GotoFoundLine();
		else // VK_DELETE
			pLogHelper->DeleteResult();*/
		return 0;
	}
	else
		// Call default (original) window procedure
		return CallWindowProc((WNDPROC) originalWndProc, hwnd, message, wParam, lParam);
}

void LogHelperDlg::findServerCalls()
{
    if (_pFinder == nullptr)
    {
        int which = -1;
        ::SendMessage(nppData._nppHandle, NPPM_GETCURRENTSCINTILLA, 0, (LPARAM)&which);
        if (which != -1)
        {
            HWND pScintillaPtr = (which == 0)?nppData._scintillaMainHandle:nppData._scintillaSecondHandle;
            _pFinder = new Finder(pScintillaPtr);
        }        
    }
    if (_pFinder)
    {
        _pFinder->FindServerCalls(std::bind(&LogHelperDlg::FoundServerCallCallback, this));
    }
}

void LogHelperDlg::FoundServerCallCallback()
{
    const FoundInfo& foundInfo = _pFinder->GetLastFoundInfo();
    _scintView.setReadOnly(false);

    _scintView.addGenericText(foundInfo._line.c_str());
    _scintView.setReadOnly(true);
}